#pragma once

#include "../widgets.h"
#include "basechart_layout.h"
#include "basechart_painter.h"

class S_WIDGETS_EXPORT BaseChartCustomTextElement {
 public:
  virtual bool customDraw(BaseChartPainter* painter, const QRect& rect) = 0;
};

#define BASECHART_TEXT_COUNT 6

class BaseChartCustomPlot;
class S_WIDGETS_EXPORT BaseChartTextElement : public BaseChartLayoutElement {
  Q_OBJECT
  /// \cond INCLUDE_QPROPERTIES
  Q_PROPERTY(QString text READ text WRITE setText)
  Q_PROPERTY(QFont font READ font WRITE setFont)
  Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
  Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
  Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE
                 setSelectedTextColor)
  Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY
                 selectableChanged)
  Q_PROPERTY(
      bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
  /// \endcond
 public:
  explicit BaseChartTextElement(BaseChartCustomPlot* parentPlot);
  BaseChartTextElement(BaseChartCustomPlot* parentPlot, const QString& text);
  BaseChartTextElement(BaseChartCustomPlot* parentPlot, const QString& text,
                       double pointSize);
  BaseChartTextElement(BaseChartCustomPlot* parentPlot, const QString& text,
                       const QString& fontFamily, double pointSize);
  BaseChartTextElement(BaseChartCustomPlot* parentPlot, const QString& text,
                       const QFont& font);
  BaseChartTextElement(BaseChartCustomPlot* parentPlot, const QString& text1,
                       const QString& text2, const QFont& font);

  // getters:
  QString text() const { return mText[0]; }
  int textFlags() const { return mTextFlags; }
  QFont font() const { return mFont; }
  QColor textColor() const { return mTextColor; }
  QFont selectedFont() const { return mSelectedFont; }
  QColor selectedTextColor() const { return mSelectedTextColor; }
  bool selectable() const { return mSelectable; }
  bool selected() const { return mSelected; }

  // setters:
  void setText(const QString& text, const QString& text2 = "",
               const QString& text3 = "", const QString& text4 = "",
               const QString& text5 = "", const QString& text6 = "");
  void setTextFlags(int flags);
  void setFont(const QFont& font);
  void setTextColor(const QColor& color);
  void setSelectedFont(const QFont& font);
  void setSelectedTextColor(const QColor& color);
  Q_SLOT void setSelectable(bool selectable);
  Q_SLOT void setSelected(bool selected);

  // reimplemented virtual methods:
  virtual double selectTest(const QPointF& pos, bool onlySelectable,
                            QVariant* details = nullptr) const Q_DECL_OVERRIDE;
  virtual void mousePressEvent(QMouseEvent* event,
                               const QVariant& details) Q_DECL_OVERRIDE;
  virtual void mouseReleaseEvent(QMouseEvent* event,
                                 const QPointF& startPos) Q_DECL_OVERRIDE;
  virtual void mouseDoubleClickEvent(QMouseEvent* event,
                                     const QVariant& details) Q_DECL_OVERRIDE;

  // other
  void setTextOffset(int offset);
  void setCustomDraw(BaseChartCustomTextElement* customTextElement);

 signals:
  void selectionChanged(bool selected);
  void selectableChanged(bool selectable);
  void clicked(QMouseEvent* event);
  void doubleClicked(QMouseEvent* event);

 protected:
  // property members:
  QString mText[BASECHART_TEXT_COUNT];
  int mTextFlags;
  int mOffset;
  QFont mFont;
  QColor mTextColor;
  QFont mSelectedFont;
  QColor mSelectedTextColor;
  QRect mTextBoundingRect;
  bool mSelectable, mSelected;
  BaseChartCustomTextElement* mCustomTextElement;

  // reimplemented virtual methods:
  virtual void applyDefaultAntialiasingHint(BaseChartPainter* painter) const
      Q_DECL_OVERRIDE;
  virtual void draw(BaseChartPainter* painter) Q_DECL_OVERRIDE;
  virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
  virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE;
  // events:
  virtual void selectEvent(QMouseEvent* event, bool additive,
                           const QVariant& details,
                           bool* selectionStateChanged) Q_DECL_OVERRIDE;
  virtual void deselectEvent(bool* selectionStateChanged) Q_DECL_OVERRIDE;

  // non-virtual methods:
  QFont mainFont() const;
  QColor mainTextColor() const;

 private:
  Q_DISABLE_COPY(BaseChartTextElement)
};

class S_WIDGETS_EXPORT BaseChartDragBarElement : public BaseChartLayoutElement {
  Q_OBJECT
  /// \cond INCLUDE_QPROPERTIES
  Q_PROPERTY(QColor barColor READ barColor WRITE setBarColor)
  Q_PROPERTY(int barHeight READ barHeight WRITE setBarHeight)
  Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY
                 selectableChanged)
  Q_PROPERTY(
      bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
  /// \endcond
 public:
  explicit BaseChartDragBarElement(BaseChartCustomPlot* parentPlot);

  // getters:
  QColor barColor() const { return mBarColor; }
  int barHeight() const { return mBarHeight; }
  bool selectable() const { return mSelectable; }
  bool selected() const { return mSelected; }

  // setters:
  void setBarColor(const QColor& color);
  void setBarHeight(int height);
  Q_SLOT void setSelectable(bool selectable);
  Q_SLOT void setSelected(bool selected);

  void setEnable(bool enable);
  void setPos(int pos1, int pos2);

  // reimplemented virtual methods:
  virtual double selectTest(const QPointF& pos, bool onlySelectable,
                            QVariant* details = nullptr) const Q_DECL_OVERRIDE;
  virtual void mousePressEvent(QMouseEvent* event,
                               const QVariant& details) Q_DECL_OVERRIDE;
  virtual void mouseMoveEvent(QMouseEvent* event,
                              const QPointF& startPos) Q_DECL_OVERRIDE;
  virtual void mouseReleaseEvent(QMouseEvent* event,
                                 const QPointF& startPos) Q_DECL_OVERRIDE;
  virtual void mouseDoubleClickEvent(QMouseEvent* event,
                                     const QVariant& details) Q_DECL_OVERRIDE;

 signals:
  void selectionChanged(bool selected);
  void selectableChanged(bool selectable);
  void clicked(QMouseEvent* event);
  void doubleClicked(QMouseEvent* event);
  void leftDrag(double ratio);
  void rightDrag(double ratio);
  void centralDrag(double ratio1, double ratio2);

 protected:
  // property members:
  QColor mBarColor;
  QRect mBarRect1, mBarRect2, mDistanceRect;
  QRect mOrgRect;
  int mBarHeight;
  int mBarPos1, mBarPos2, mPos12;
  bool mDragging1, mDragging2, mDragging12;
  bool mSelectable, mSelected;
  bool mEnable;

  // reimplemented virtual methods:
  virtual void applyDefaultAntialiasingHint(BaseChartPainter* painter) const
      Q_DECL_OVERRIDE;
  virtual void draw(BaseChartPainter* painter) Q_DECL_OVERRIDE;
  virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
  virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE;
  // events:
  virtual void selectEvent(QMouseEvent* event, bool additive,
                           const QVariant& details,
                           bool* selectionStateChanged) Q_DECL_OVERRIDE;
  virtual void deselectEvent(bool* selectionStateChanged) Q_DECL_OVERRIDE;

  // non-virtual methods:
  void drawBk(BaseChartPainter* painter);
  void drawBar(BaseChartPainter* painter);

 private:
  Q_DISABLE_COPY(BaseChartDragBarElement)
};
